<?php

class ProducerModel{
	
	private $database;
	
	private $responsType;
	
	private $producersArray;
	
	function __construct(DBConnection $a_DB, $a_responseType){
		$this->database = $a_DB;
		$this->responsType = $a_responseType;
	}
	
	/**
	 * Function to get all Producers
	 * @access public
	 * @param -
	 * @return array with pruducers
	 */
	public function getAllProducers(){
		$query = "SELECT ProducerId, longitude, latitude, description FROM Producer ORDER BY ProducerId";
		$sth = $this->database->prepare($query);
		$sth->execute();
		$returnArray = array();
		
		while($result = $sth->fetch(PDO::FETCH_ASSOC)){
			$returnArray[] = $result;
		}
		
		return $this->setReturnFormat($returnArray);
		
	}
	
	/**
	 * Function to get Producer by Id
	 * @access public
	 * @param int id
	 * @return pruducer
	 */
	function getProducerById($a_id){
		$query = "SELECT ProducerId, longitude, latitude, description FROM Producer WHERE ProducerId = ?";
		$sth = $this->database->prepare($query);
		$sth->bindParam(1, $a_id);
		$sth->execute();
		$returnArray['position'] = $sth->fetch(PDO::FETCH_ASSOC);
		
		if($returnArray['position'] == false){
			return $this->setBadRequestHeader("ID Out of scope", "404 NotFound");
		}
		
		return $this->setReturnFormat($returnArray);
	}
	
	/**
	 * Function to Create producer
	 * @access public
	 * @param array data
	 * @return Created producer
	 */
	function createProducer($values){
		$query = $query = "INSERT INTO 'Producer' (ProducerId, longitude, latitude, description) VALUES(?, ?, ?, ?);";
		$sth = $this->database->prepare($query);
		$sth->bindParam(1, $values['ProducerId']);
		$sth->bindParam(2, $values['Longitude']);
		$sth->bindParam(3, $values['Latitude']);
		$sth->bindParam(4, $values['Description']);
		
		try{
			$sth->execute();
		}
		catch(PDOException $e){
			return $this->setBadRequestHeader("Could not insert: " . $e->getMessage(), "400");
		}
		
		header('HTTP/1.1 201 Created');
        return $this->getProducerById($this->database->lastInsertId()) ;
		
	}
	
	/**
	 * Function to update producer
	 * @access public
	 * @param array data
	 * @return updated producer
	 */
	function updateProducer($id, $values){
		$values['Description'] = urldecode($values['Description']);
		
		$query = "UPDATE 'Producer' SET longitude = ?, latitude = ?, description =? WHERE ProducerId=?;";
		$sth = $this->database->prepare($query);
		$sth->bindParam(1, $values['Longitude']);
		$sth->bindParam(2, $values['Latitude']);
		$sth->bindParam(3, $values['Description']);
		$sth->bindParam(4, $id);
		$sth->execute();
		$count = $sth->rowCount();
		
		if($count<1){
			return $this->setBadRequestHeader("Could not update!");
		}
		
		return $this->getProducerById($id);
	}
	
	/**
	 * Function to delete Producer
	 * @access public
	 * @param array with ProducerId
	 * @return -
	 */
	function deleteProducerById($id){
		$query = "DELETE FROM 'Producer' WHERE ProducerId=?;";
		$sth = $this->database->prepare($query);
		$sth->bindParam(1, $id);
		$sth->execute();
		$count = $sth->rowCount();
		
		if($count<1){
			return $this->setBadRequestHeader("Could not Delete given ID!");
			
		}
		$this->setOkRequestHeader($this->responsType);
		return;
	}
	
	/**
	 * Function to validate posted data before update/insert
	 * @access private
	 * @param array with data
	 * @return bool
	 */
	private function validateProducerData($data){
		if(!is_float($data['Longitude']) ||
			!is_float($data['Latitude'])){
			return false;
		}
		return true;
	}
	/**
	 * Function to encode returnstring as requested
	 * @access private
	 * @param array
	 * @return XML/JSON
	 */
	private function setReturnFormat($a_array){
		if($this->responsType == "application/json"){
			$this->setOkRequestHeader("json");
			return json_encode($a_array, JSON_FORCE_OBJECT);
		}
		$this->setOkRequestHeader("xml");
		//return $this->arrayToXml("Position", $a_array);
		return $this->array2xml($a_array);
	}
	
	/**
	 * Function to set Responsheader xml or json
	 * @access public
	 * @param string type (xml or json)
	 * @return -
	 */
	function setOkRequestHeader($type){
		header('HTTP/1.1 200 Ok');	
		header('Charset:utf-8;');
		header('Content-Type: application/'.$type);
	}
	
	/**
	 * Function to set the bad request header
	 * @access private
	 * @param error string
	 * @return error string
	 */
	function setBadRequestHeader($error = null, $code="400 Bad Request"){
		header('HTTP/1.1 '.$code."'");
		header('Content-Type: application/xml');
		
		if($error == null){
			$error = "<error>Bad Request</error>";
		}
		else{
			$error = "<error>" . $error . "</error>";
		}
		
		return $error;
	}
	
	/**
	 * Function to convert an array into xml
	 * @access private
	 * @param array
	 * @return XML
	 */
	function arrayToXml($root_element_name, $ar) {
		$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding='UTF-8'?><{$root_element_name}></{$root_element_name}>"); 
    		$f = create_function('$f,$c,$a',' 
	            foreach($a as $k=>$v) {
	        		if(is_int($k)){
	        			$k = "Producer";
	        		}
	            	if(is_array($v)) {
	            		$ch=$c->addChild($k); 
	                    $f($f,$ch,$v); 
	                } else { 
	                    $c->addChild($k,$v); 
	                } 
	            }'); 
			
    	$f($f,$xml,$ar); 
		return $xml->asXML();
	}
	
	/**
	 * Function to generate XML from array with producers
	 * @access public
	 * @param array
	 * @return xml
	 */
	function array2xml($a_array){
		$string = "<positions>";
		
		foreach($a_array as $key => $position){
				
			$string .= "<position>" . 
							"<producerId>" . $position['ProducerId']. "</producerId>" .
							"<longitude>" . $position['longitude'] . "</longitude>" . 
							"<latitude>" . $position['latitude'] . "</latitude>" .
							"<description>" . $position['description'] . "</description>" .
						"</position>";
		}
		
		$string .= "</positions>";
		
		$xml = simplexml_load_string($string);
		return $xml->asXML();
	}
	
}
?>